﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.ApplicationPages;
using Microsoft.SharePoint.Utilities;
using System.Collections.Generic;

namespace ListLimiter.Layouts
{
    public partial class ListLimiterSettingsPage : LayoutsPageBase
    {
        private Guid _listId;
        public Guid ListId
        {
            get
            {
                if (_listId == Guid.Empty)
                {
                    string listIdRequest = this.Page.Request["ListId"];
                    _listId = new Guid(listIdRequest);
                }

                return _listId;
            }
        }

        private SPList _list;
        public SPList List
        {
            get
            {
                if (_list == null)
                {
                    _list = this.Web.Lists[this.ListId];
                }
                return _list;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            SetControlDefault();
            SetControlLabels();
        }

        private void SetControlLabels()
        {
            //Enable/disable configuration
            literalEnableLimit.Text = Common.GetLocalizedString(this.Web, "Settings_Literal_Enable");
            literalInputLimit.Text = Common.GetLocalizedString(this.Web, "Settings_Literal_InputLimit");

            InputFormSection section = inputSectionLimit as InputFormSection;
            section.Title = Common.GetLocalizedString(this.Web, "Settings_InputFormSection_Title");
            inputSectionDescriptionLimit.Text = Common.GetLocalizedString(this.Web, "Settings_InputFormSection_Description");
            literalPageTitle.Text = Common.GetLocalizedString(this.Web, "Settings_Page_Title");
            literalPageTitleInTitle.Text = Common.GetLocalizedString(this.Web, "Settings_Page_Title");

            //Status configuration
            InputFormSection sectionStatus = inputSectionLimitStatus as InputFormSection;
            sectionStatus.Title = Common.GetLocalizedString(this.Web, "Settings_InputFormSection_Status_Title");

            inputSectionDescriptionLimitStatus.Text = Common.GetLocalizedString(this.Web, "Settings_InputFormSection_Status_Description");
            literalLimitStatusText.Text = Common.GetLocalizedString(this.Web, "Settings_Literal_Status_Title"); 
            literalLimitStatusTitle.Text = Common.GetLocalizedString(this.Web, "Settings_Literal_Status_Text"); 
            literalEnableLimitStatus.Text = Common.GetLocalizedString(this.Web, "Settings_Literal_Status_Enabled");
        }

        private void SetControlDefault()
        {
            if (!this.Page.IsPostBack)
            {
                int limit = Common.GetLimit(this.Web, this.ListId);
                bool limitEnabled = Common.GetLimitEnabled(this.Web, this.ListId);
                bool statusEnabled = Common.GetLimitStatusEnabled(this.Web, this.ListId);
                string statusTitle = Common.GetLimitStatusTitle(this.Web, this.ListId, false);
                string statusText = Common.GetLimitStatusText(this.Web, this.ListId, false);


                inputLimit.Text = limit.ToString();
                chkEnableLimit.Checked = limitEnabled;
                chkDisableLimit.Checked = !limitEnabled;
                inputLimitStatusTitle.Text = statusTitle;
                inputLimitStatusText.Text = statusText;
                chkEnableLimitStatus.Checked = statusEnabled;
                chkDisableLimitStatus.Checked = !statusEnabled;
            }
        }

        public void BtnSave_Click(object sender, EventArgs e)
        {
            int limit = GetInputLimit();
            bool limitEnabled = GetCheckBoxValue();
            
            string statusTitle = inputLimitStatusTitle.Text;
            string statusText = inputLimitStatusText.Text;
            bool statusEnabled = chkEnableLimitStatus.Checked;

            Common.SetLimit(this.Web, this.ListId, limit);
            Common.SetLimitEnabled(this.Web, this.ListId, limitEnabled);
            Common.SetLimitStatusTitle(this.Web, this.ListId, statusTitle);
            Common.SetLimitStatusText(this.Web, this.ListId, statusText);
            Common.SetLimitStatusEnabled(this.Web, this.ListId, statusEnabled);

            if (limitEnabled)
            {
                RegisterEventReceiver();
            }
            else
            {
                DeleteEventReceiver();
            }

            SPUtility.Redirect(string.Empty, SPRedirectFlags.UseSource, this.Context);
        }

        private void DeleteEventReceiver()
        {
            List<SPEventReceiverDefinition> receiversToDelete = GetLimitEventReceivers(); 

            foreach (SPEventReceiverDefinition receiver in receiversToDelete)
            {
                receiver.Delete();
            }
        }

        private void RegisterEventReceiver()
        {
            if (!EventReceiverExists())
            {
                SPEventReceiverType receiverTypeItemAdding = SPEventReceiverType.ItemAdding;
                Type receiverType = typeof(ListLimiterReceiver);
                string receiverAssembly = receiverType.Assembly.FullName;
                string receiverClass = receiverType.FullName;

                this.List.EventReceivers.Add(receiverTypeItemAdding, receiverAssembly, receiverClass);
            }
        }

        private bool EventReceiverExists()
        {
            List<SPEventReceiverDefinition> receivers = GetLimitEventReceivers();
            bool exist = receivers.Count > 0;

            return exist;
        }

        private List<SPEventReceiverDefinition> GetLimitEventReceivers()
        {
            List<SPEventReceiverDefinition> returnReceivers = new List<SPEventReceiverDefinition>();
            SPEventReceiverDefinitionCollection receivers = this.List.EventReceivers;


            foreach (SPEventReceiverDefinition receiver in receivers)
            {
                if (receiver.Assembly == typeof(ListLimiterReceiver).Assembly.FullName)
                {
                    returnReceivers.Add(receiver);
                }
            }

            return returnReceivers;
        }

        private bool GetCheckBoxValue()
        {
            return chkEnableLimit.Checked;
        }

        private int GetInputLimit()
        {
            int limit = 0;
            string inputLimitString = inputLimit.Text;
            if (!string.IsNullOrEmpty(inputLimitString))
            {
                limit = Convert.ToInt32(inputLimitString);
            }

            return limit;
        }
    }
}
